package io.cici.cc.mybatis.lite.type;

import io.cici.cc.mybatis.lite.session.Configuration;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public abstract class BaseTypeHandler<T> extends TypeReference<T> implements TypeHandler<T> {


    protected Configuration configuration;


    public void setConfiguration(Configuration c) {
        this.configuration = c;
    }

    @Override
    public void set(PreparedStatement preparedStatement, int index, Object parameter)
            throws SQLException {
        if (parameter == null) {

            try {
                preparedStatement.setObject(index, null);
            } catch (SQLException e) {
                throw new TypeException("Error setting null for parameter #" + index + " with JdbcType "
                        + " . "
                        + "Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. "
                        + "Cause: " + e, e);
            }
        } else {
            try {
                setNonNullParameter(preparedStatement, index, (T) parameter);
            } catch (Exception e) {
                throw new TypeException("Error setting non null for parameter #" + index + " with JdbcType "
                        + " . "
                        + "Try setting a different JdbcType for this parameter or a different configuration property. "
                        + "Cause: " + e, e);
            }
        }
    }

    @Override
    public T get(ResultSet resultSet, String columnName) throws SQLException {
        try {
            return getNullableResult(resultSet, columnName);
        } catch (Exception e) {
            throw new SQLException("Error attempting to get column '" + columnName + "' from result set.  Cause: " + e,
                    e);
        }
    }

    @Override
    public T get(ResultSet resultSet, int columnIndex) throws SQLException {
        try {
            return getNullableResult(resultSet, columnIndex);
        } catch (Exception e) {
            throw new SQLException("Error attempting to get column #" + columnIndex + " from result set.  Cause: " + e,
                    e);
        }
    }

    public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter)
            throws SQLException;

    /**
     * Gets the nullable result.
     *
     * @param rs         the rs
     * @param columnName Column name, when configuration <code>useColumnLabel</code>
     *                   is <code>false</code>
     * @return the nullable result
     * @throws SQLException the SQL exception
     */
    public abstract T getNullableResult(ResultSet rs, String columnName) throws SQLException;

    public abstract T getNullableResult(ResultSet rs, int columnIndex) throws SQLException;

}
